home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / share / dos / graficos / plydat14.arj / SPHCOIL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-29  |  5.0 KB  |  189 lines

  1. /*
  2.  * coil.c - Create a coil of n turns between two points in space
  3.  *
  4.  * Alexander Enzmann
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #ifdef MAC
  11. #include <console.h>
  12. #endif
  13. #include "def.h"
  14. #include "lib.h"
  15.  
  16. static void
  17. determine_coil_point(COORD4 *pos, COORD4 *norm,
  18.              double theta, double phi, double r0, double r1, double d0)
  19. {
  20.    COORD4 v0, v1, vd;
  21.    double len;
  22.  
  23.    /* Center of the coil */
  24.    SET_COORD4(v0, r0 * cos(theta), r0 * sin(theta), d0, 1.0);
  25.  
  26.    /* Point on the coil */
  27.    SET_COORD4(*pos, (r0 + r1 * sin(phi)) * cos(theta),
  28.             (r0 + r1 * sin(phi)) * sin(theta),
  29.             (r1 * cos(phi)) + d0,
  30.             1.0);
  31.  
  32.    /* Direction from center to point */
  33.    SUB3_COORD(vd, *pos, v0);
  34.    len = lib_normalize_coord3(&vd);
  35.  
  36.    v0.x = r1*cos(phi)*cos(theta);
  37.    v1.x = -(r0 + r1*sin(phi))*sin(theta);
  38.  
  39.    v0.y = r1*cos(phi)*sin(theta);
  40.    v1.y = (r0 + r1*sin(phi))*cos(theta);
  41.  
  42.    v0.z = -r1*sin(phi);
  43.    v1.z = 0.0;
  44.  
  45.    CROSS(*norm, v0, v1);
  46.    len = lib_normalize_coord3(norm);
  47.  
  48.    len = DOT_PRODUCT(*norm, vd);
  49.    if (len < 0.0) {
  50.       norm->x *= -1.0;
  51.       norm->y *= -1.0;
  52.       norm->z *= -1.0;
  53.       }
  54.    norm->w = 0.0;
  55. }
  56.  
  57. /* Wrap a coil around a sphere of radius sr, centered at d=t */
  58. static void
  59. generate_cyl_coil(COORD4 *start, COORD4 *end,
  60.          int turns, int step_per_turn,
  61.          double r0, double r1,
  62.          double t, double sr,
  63.          char *txname)
  64. {
  65.    int i, j, k;
  66.    COORD4 p, p0, p1, n0;
  67.    COORD4 dir;
  68.    MATRIX trans;
  69.    double dist, u0, u1, d0, d1, len;
  70.    double deltad, deltau;
  71.    double t0, t1, tm;
  72.    double rt, q, rdif = r0 - r1, sr2 = sr * sr;
  73.  
  74.    SUB3_COORD(dir, *end, *start);
  75.    dist = lib_normalize_coord3(&dir);
  76.  
  77.    /* Coils are sorta complex, so make bounding slabs oriented along
  78.       the direction of the coil */
  79.    lib_output_bounding_slab(&dir);
  80.  
  81.    /* Figure out the transform to get from the parametrically defined
  82.       coil to the start-end line */
  83.    lib_create_canonical_matrix(trans, start, &dir);
  84.  
  85.    /* Figure out the lower and upper limits that the sphere will
  86.       affect the coil */
  87.    t0 = dist * t - sr;
  88.    t1 = dist * t + sr;
  89.    tm = (t1 + t0) / 2.0;
  90.  
  91.    /* Calculate the step sizes for making the coil */
  92.    deltad = dist / (double)(turns * step_per_turn);
  93.    deltau = 2.0 * PI / (double)step_per_turn;
  94.  
  95.    /* Start generating the cylinders making up the coil */
  96.    for (i=0,d0=0.0;i<turns;i++) {
  97.       for (j=0;j<step_per_turn;j++,d0+=deltad) {
  98.          d1 = d0 + deltad;
  99.      u0 = (double)j * deltau;
  100.      u1 = u0 + deltau;
  101.      if (d0 > t0 && d0 < t1) {
  102.         q = fabs(d0 - tm);
  103.         q = sqrt(sr2 - q * q);
  104.         if (q > rdif)
  105.            rt = r0 + (q - rdif);
  106.         else
  107.            rt = r0;
  108.         }
  109.      else
  110.         rt = r0;
  111. /* fprintf(stderr, "d: %g, rt: %g\n", d0, rt); */
  112.      determine_coil_point(&p, &n0, u0, 0.0, rt, 0.0, d0);
  113.      lib_transform_coord(&p0, &p, trans);
  114.      p0.w = r1;
  115.      if (d1 > t0 && d1 < t1) {
  116.         q = fabs(d1 - tm);
  117.         q = sqrt(sr2 - q * q);
  118.         if (q > rdif)
  119.            rt = r0 + (q - rdif);
  120.         else
  121.            rt = r0;
  122.         }
  123.      else
  124.         rt = r0;
  125.      determine_coil_point(&p, &n0, u1, 0.0, rt, 0.0, d1);
  126.      lib_transform_coord(&p1, &p, trans);
  127.      p1.w = r1;
  128.      lib_output_cylcone(&p0, &p1, txname);
  129.      lib_output_sphere(&p0, txname);
  130.      }
  131.       }
  132.    /* Cap the end */
  133.    lib_output_sphere(&p1, txname);
  134. }
  135.  
  136. void
  137. main(int argc, char *argv[])
  138. {
  139.     COORD4  back_color, coil_color, dir;
  140.     COORD4  center_pt, end_pt, light;
  141.     COORD4  from, at, up;
  142.     char *txname;
  143.  
  144.     MATRIX m1, m2;
  145.  
  146. #ifdef MAC
  147.    argc = ccommand(&argv);
  148. #endif
  149.  
  150.     /* output viewpoint */
  151.     SET_COORD(from, 0.0, 7.0,-7.0);
  152.     SET_COORD(at,   0.0, 1.0, 2.0);
  153.     SET_COORD(up,   0.0, 1.0, 0.0);
  154.     lib_output_viewpoint(&from, &at, &up, 30.0, 1.0, 1.0, 256, 256);
  155.  
  156.     /* output background color - dark blue */
  157.     SET_COORD(back_color, 0.039, 0.18, 0.376);
  158.     lib_output_background_color(&back_color);
  159.  
  160.     /* Output bounding slabs oriented along the coordinate axes */
  161.     SET_COORD(dir, 1.0, 0.0, 0.0);
  162.     lib_output_bounding_slab(&dir);
  163.     SET_COORD(dir, 0.0, 1.0, 0.0);
  164.     lib_output_bounding_slab(&dir);
  165.     SET_COORD(dir, 0.0, 0.0, 1.0);
  166.     lib_output_bounding_slab(&dir);
  167.  
  168.     /* output light source */
  169.     SET_COORD(light,-10.0, 10.0,-20.0);
  170.     lib_output_light(&light);
  171.     SET_COORD(light, 10.0, 10.0,-20.0);
  172.     lib_output_light(&light);
  173.  
  174.     /* output sphere color - blue */
  175.     SET_COORD4(center_pt, 0.0, 1.0, 2.0, 1.5);
  176.     SET_COORD(coil_color, 0.2, 0.2, 1.0);
  177.     txname = lib_output_color(&coil_color, 0.1, 0.1, 0.4, 3.0, 0.0, 0.8, 1.3);
  178.     lib_output_sphere(¢er_pt, txname);
  179.  
  180.     /* output coil color - red */
  181.     SET_COORD(coil_color, 1.0, 0.2, 0.2);
  182.     txname = lib_output_color(&coil_color, 0.2, 0.8, 0.4, 5.0, 0.0, 0.0, 0.0);
  183.  
  184.     /* compute and output coil */
  185.     SET_COORD4(center_pt,-1.0,-1.0, 0.0, 1.0);
  186.     SET_COORD4(end_pt, 1.0, 3.0, 4.0, 1.0);
  187.     generate_cyl_coil(¢er_pt, &end_pt, 24, 72, 1.0, 0.05, 0.5, 1.5, txname);
  188. }
  189.